/*****************************************************************************
 * Copyright (C) Stacy Curl. All rights reserved.                            *
 * ------------------------------------------------------------------------- *
 * The software in this package is published under the terms of the BSD      *
 * style license a copy of which has been included with this distribution in *
 * the LICENSE.txt file.                                                     *
 *****************************************************************************/
package picounit.features.test_factory;

import picounit.features.aggregate_exception.Thrower;
import picounit.features.class_finder.ClassFinder;
import picounit.features.mock_collaborator_injection.CollaboratorsInvocationHandler;
import picounit.features.registry.RegistryFactory;
import picounit.features.registry.Resolver;
import picounit.features.test_instantiator.Instantiator;
import picounit.features.test_instantiator.Invoker;
import picounit.features.test_instantiator.InvokerFactory;
import picounit.features.test_instantiator.LifecycleInstantiator;
import picounit.features.test_instantiator.LifecycleInstantiatorImpl;
import picounit.features.test_instantiator.OrdinaryInstantiatorFactory;
import picounit.mocker.MockControl;

import java.lang.reflect.Method;

import junit.framework.Test;

public class TestFactory {
	private final RegistryFactory registryFactory;
	private final ClassFinder classFinder;
	private final MockControl mockControl;
	private final Thrower thrower;
	private final TestListener testListener;
	private final ClassLoader classLoader;
	private final CollaboratorsInvocationHandler collaboratorsInvocationHandler;
	private final InvokerFactory invokerFactory;
	private final OrdinaryInstantiatorFactory instantiatorFactory;
	
	public TestFactory(RegistryFactory registryFactory, ClassLoader classLoader, Thrower thrower,
		TestListener testListener, MockControl mockControl,
		CollaboratorsInvocationHandler collaboratorsInvocationHandler, ClassFinder classFinder,
		InvokerFactory invokerFactory, OrdinaryInstantiatorFactory instantiatorFactory) {

		this.registryFactory = registryFactory;
		this.mockControl = mockControl;
		this.collaboratorsInvocationHandler = collaboratorsInvocationHandler;
		this.classFinder = classFinder;
		this.classLoader = classLoader;
		this.thrower = thrower;
		this.testListener = testListener;
		this.invokerFactory = invokerFactory;
		this.instantiatorFactory = instantiatorFactory;
	}

	public <T> Test create(Class<T> testClass, Method testMethod) {
		Resolver resolver = registryFactory.create();

		Invoker invoker = invokerFactory.create(resolver);
		// TODO: Replace this with multiple TestListeners

		Instantiator instantiator = instantiatorFactory.create(resolver);

		LifecycleInstantiator lifecycleInstantiator = 
			new LifecycleInstantiatorImpl(classLoader, instantiator, classFinder);

		testListener.testPrepared();

		return new PicoUnitTestCase<T>(testClass, testMethod, instantiator, invoker, mockControl, thrower,
			lifecycleInstantiator, testListener, collaboratorsInvocationHandler);
	}
}
